package org.xx.armory.rpc;

import org.xx.armory.commons.StreamWriter;

import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Date;

/**
 * RPC响应。
 *
 * @author Haart
 */
public interface RpcResponse
        extends AutoCloseable {
    /**
     * 设置响应内容长度。
     *
     * @param contentSize
     *         响应内容长度。
     * @throws IllegalArgumentException
     *         如果参数{@code contentSize}小于{@code 0}。
     */
    void setContentSize(
            long contentSize
    );

    /**
     * 设置响应内容的类型。
     *
     * @param contentType
     *         响应内容的类型，自动去掉首尾空格。
     * @param charset
     *         响应内容的编码，{@code null}表示未设置编码。
     * @throws IllegalArgumentException
     *         如果参数{@code contentType}是{@code null}或者只包含空白字符。
     */
    void setContentType(
            String contentType,
            Charset charset
    );

    /**
     * 设置响应内容的日期。
     *
     * @param date
     *         响应内容的日期，{@code null}表示未设置日期。
     */
    void setDate(
            Date date
    );

    /**
     * 获取和响应内容一同发送的Cookie集合。
     *
     * @return 和响应内容一同发送的Cookie的集合。
     */
    Collection<RpcCookie> getCookies();

    /**
     * 设置RPC响应为内容。
     *
     * @param writer
     *         输出响应内容的函数。
     * @throws IllegalArgumentException
     *         如果参数{@code writer}是{@code null}。
     * @throws ResponseException
     *         如果输出响应时出现错误。
     */
    void ok(
            StreamWriter writer
    );

    /**
     * 设置RPC响应为无效的请求。
     *
     * @throws ResponseException
     *         输出响应时出现错误。
     */
    void badRequest();

    /**
     * 设置RPC响应为未找到资源。
     *
     * @throws ResponseException
     *         输出响应时出现错误。
     */
    void notFound();

    /**
     * 设置RPC响应为访问被拒绝。
     *
     * @throws ResponseException
     *         输出响应时出现错误。
     */
    void accessDenied();

    /**
     * 设置RPC响应为内部错误。
     *
     * @param t
     *         导致内部错误的异常。
     * @throws ResponseException
     *         输出响应时出现错误。
     */
    void exception(
            Throwable t
    );

    /**
     * 放弃整个RPC响应。
     * <p>此方法直接废弃整个RPC响应，不再尝试向客户端发送任何消息。</p>
     *
     * @param t
     *         导致放弃的异常。
     */
    void abandon(
            Throwable t
    );
}
